package vg.services.graph_view_manager.realization.graph_view.smart_graph_view.realization;

import java.util.Set;

import javax.swing.JComponent;

import vg.services.graph_view_manager.interfaces.graph_view.IHighLevelGraphEditor;
import vg.services.graph_view_manager.realization.graph_view.smart_graph_view.interfaces.ISGVGraphView4Patching;
import vg.services.graph_view_manager.realization.graph_view.smart_graph_view.interfaces.ISGVPatchManager;
import vg.services.graph_view_manager.realization.graph_view.smart_graph_view.realization.patches.DefaultPatch;
import vg.services.graph_view_manager.realization.graph_view.smart_graph_view.realization.patches.ExecuteLayoutPatch;
import vg.services.graph_view_manager.realization.graph_view.smart_graph_view.shared.Utils;

/**
 * Implementation of IHighLevelGraphEditor.
 * @author Timur Zolotuhin (e-mail: tzolotuhin@gmail.com)
 */
public class SGVHighLevelGraphEditor implements IHighLevelGraphEditor {
	// Main components
	private ISGVPatchManager sgv_patch_manager;

	/**
	 * Constructor.
	 */
	public SGVHighLevelGraphEditor(ISGVPatchManager sgv_patch_manager) {
		this.sgv_patch_manager = sgv_patch_manager;
	}
//=============================================================================
//-----------------Undo/Redo methods-------------------------------------------
	@Override
	public void undo() {
		DefaultPatch patch = new DefaultPatch("Undo") {
			@Override
			public void apply(ISGVGraphView4Patching graphView4patching) {
				graphView4patching.undo();
			}
		};
		
		sgv_patch_manager.addPatch(patch);		
	}
	
	@Override
	public void redo() {
		DefaultPatch patch = new DefaultPatch("Redo") {
			@Override
			public void apply(ISGVGraphView4Patching graphView4patching) {
				graphView4patching.redo();
			}
		};
		
		sgv_patch_manager.addPatch(patch);		
	}
		
//=============================================================================
//-----------------Layout methods----------------------------------------------
	@Override
	public void executeCurrentLayout() {
		sgv_patch_manager.addPatch(new ExecuteLayoutPatch());
	}
	
//=============================================================================
//-----------------Panning-----------------------------------------------------
	public void setPanning(final boolean panning) {
		DefaultPatch patch = new DefaultPatch("setPanning") {
			@Override
			public void apply(ISGVGraphView4Patching graphView4patching) {
				graphView4patching.setPanning(panning);
			}
		};
		
		sgv_patch_manager.addPatch(patch);
	}

	public boolean isPanning() {
		DefaultPatch patch = new DefaultPatch("isPanning") {
			@Override
			public void apply(ISGVGraphView4Patching graphView4patching) {
				result = graphView4patching.isPanning();
			}
		};
		
		Utils.add_patch2patch_manager_and_wait_result(sgv_patch_manager, patch);		
		Object result = patch.getResult();
		if (result != null)
			return (Boolean)result;
		return false;
	}	
			
//=============================================================================
//-----------------Methods for changing visualization from elements------------
	@Override
	public void setInvisibleAllEdgesBut(final Set<Integer> edgeIds) {
		DefaultPatch patch = new DefaultPatch("setInvisibleAllEdgesBut") {
			@Override
			public void apply(ISGVGraphView4Patching graphView4patching) {
				graphView4patching.setInvisibleAllEdgesBut(edgeIds);
			}
		};
		
		sgv_patch_manager.addPatch(patch);
	}
	
	@Override
	public void setInvisibleAllVerticesBut(final Set<Integer> vertexIds) {
		DefaultPatch patch = new DefaultPatch("setInvisibleAllVerticesBut") {
			@Override
			public void apply(ISGVGraphView4Patching graphView4patching) {
				graphView4patching.setInvisibleAllVerticesBut(vertexIds);
			}
		};
		
		sgv_patch_manager.addPatch(patch);
	}
	
	@Override
	public void setInvisibleEdges(final Set<Integer> edgeIds) {
		DefaultPatch patch = new DefaultPatch("setInvisibleEdges") {
			@Override
			public void apply(ISGVGraphView4Patching graphView4patching) {
				graphView4patching.setInvisibleVertices(edgeIds);
			}
		};
		
		sgv_patch_manager.addPatch(patch);
	}
	
	@Override
	public void setInvisibleVertices(final Set<Integer> vertexIds) {
		DefaultPatch patch = new DefaultPatch("setInvisibleVertices") {
			@Override
			public void apply(ISGVGraphView4Patching graphView4patching) {
				graphView4patching.setInvisibleVertices(vertexIds);
			}
		};
		
		sgv_patch_manager.addPatch(patch);
	}
	
	@Override
	public void setSelectionElements(final Set<Integer> lvsids, final Set<Integer> lesids) {
		DefaultPatch patch = new DefaultPatch("setSelectionElements") {
			@Override
			public void apply(ISGVGraphView4Patching graphView4patching) {
				graphView4patching.setSelectionElements(lvsids, lesids);
			}
		};
		
		sgv_patch_manager.addPatch(patch);
	}
	
	@Override
	public void showAttributes(final Set<String> vertexAttr, final Set<String> edgeAttr) {
		DefaultPatch patch = new DefaultPatch("showAttributes") {
			@Override
			public void apply(ISGVGraphView4Patching graphView4patching) {
				graphView4patching.showAttributes(vertexAttr, edgeAttr);
			}
		};
		
		sgv_patch_manager.addPatch(patch);
	}

//=============================================================================
//-----------------Methods for scaling graph-----------------------------------
	@Override
	public void zoomIn() {
		DefaultPatch patch = new DefaultPatch("zoomIn") {
			@Override
			public void apply(ISGVGraphView4Patching graphView4patching) {
				graphView4patching.zoomIn();
			}
		};
		
		sgv_patch_manager.addPatch(patch);
	}

	@Override
	public void zoomOut() {
		DefaultPatch patch = new DefaultPatch("zoomOut") {
			@Override
			public void apply(ISGVGraphView4Patching graphView4patching) {
				graphView4patching.zoomOut();
			}
		};
		
		sgv_patch_manager.addPatch(patch);
	}

//	@Override
//	public void setZoom(String scale) {
		
//	}
	
	/**
     * This method enable/disable relationship between combobox and model scale
     * 
     * @param enable
     *          - if true then changing scaling in model change value in combobox
     * @param zoomCombo
     *          - combobox that should use for represent scale
     */
//	    void setEnableZoomComboToGraphView(boolean enable, ZoomComboBox zoomCombo);
}
